package com.hardson.toolkit.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author hardson
 * @description TODO
 * @date 2023/7/27 上午12:33
 * Deprecated and changed to ReflectUtil
 */
@Deprecated
public class MethodUtil {

    public static Object invoke(//
                                final Object obj, //
                                final String methodName) throws IllegalAccessException, InvocationTargetException {
        Method method = getMethod(obj, methodName, null);
        if (method != null) {
            return method.invoke(obj);
        }
        return null;
    }

    public static Object invoke(//
                                final Object obj, //
                                final String methodName, //
                                final Object[] args, //
                                final Class<?>[] parameterTypes)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Method method = getMethod(obj, methodName, parameterTypes);
        if (method != null) {
            return method.invoke(obj, args);
        }
        throw new NoSuchMethodException("methodName:" + methodName);
    }

    public static Method getMethod(//
                                   final Object obj, //
                                   final String methodName, //
                                   final Class<?>[] parameterTypes) {
        Class<? extends Object> clazz = obj.getClass();
        Method method = null;
        try {
            method = clazz.getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e) {
        }
        if (method == null) {
            try {
                method = clazz.getDeclaredMethod(methodName, parameterTypes);
                method.setAccessible(true);
            } catch (NoSuchMethodException e) {
            }
        }
        return method;
    }

    public static String toMethodName(String fieldName, final String prefix) {
        if (fieldName == null || (fieldName = fieldName.trim()).length() == 0) {
            return null;
        }
        String firstChar = getFirstUpperChar(fieldName);
        return String.join(firstChar, prefix, fieldName.substring(1));
    }

    public static Object invokeGet(Object obj, String fieldName)
            throws IllegalAccessException, InvocationTargetException {
        String firstChar = getFirstUpperChar(fieldName);
        String methodName = String.join(firstChar, "get", fieldName.substring(1));
        return invoke(obj, methodName);
    }

    public static Object invokeIs(Object obj, String fieldName)
            throws IllegalAccessException, InvocationTargetException {
        String firstChar = getFirstUpperChar(fieldName);
        String methodName = String.join(firstChar, "is", fieldName.substring(1));
        return invoke(obj, methodName);
    }

    public static Object invokeSet(Object obj, String fieldName, Object[] args, Class<?>[] parameterTypes)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        String firstChar = getFirstUpperChar(fieldName);
        String methodName = String.join(firstChar, "set", fieldName.substring(1));
        return invoke(obj, methodName, args, parameterTypes);
    }

    private static String getFirstUpperChar(String fieldName) {
        return fieldName.substring(0, 1).toUpperCase();
    }
}
